home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 20
/
Cream of the Crop 20 (Terry Blount) (1996).iso
/
math
/
alged34.zip
/
ALGEDSRC.ZIP
/
ALGRAPH.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-06
|
26KB
|
839 lines
/*--------------------------------------------------------------------
Alged: Algebra Editor henckel@vnet.ibm.com
Copyright (c) 1994 John Henckel
Permission to use, copy, modify, distribute and sell this software
and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies.
*/
#include "alged.h"
#include <graphics.h>
#include <dos.h>
/*
xs is size
xo is origin (left edge)
xz is maxx/xs (number of pixels per unit length)
np is number of points
*/
static node* defx; // default fx
static double xs=0,xo,ys,yo,xz,yz,np,ts,to;
static double err,step;
static node ivar[10]; /* independent variables */
static int gm,polar,nv,rain,fill;
static int co1,co2,co3; /* colors */
extern char gdriver[80];
extern int gmode,psz,pst;
/*-----------------------------------------------------------------
Palette variables
*/
typedef struct { unsigned char r,g,b; } palen;
static palen pal[480];
static int v256;
/*-----------------------------------------------------------------
3d variables
*/
static int in3d,vix=1;
static double focalen = 5, cont;
static double cx,cy,cz; // camera location
static double ax,ay,az; // camera orientation
static double m[4][4]; // transform matrix
extern double lightx,lighty,lightz; // see algfile.c
#define EPS 1E-200
/* These are the zooming ratios.... rr1 is (1-rr)/2 */
#define rr 0.7
#define rr1 0.15
#define tt (M_PI/72)
typedef struct { // save previous row data for polyfill
short x2,y2; // screen location
} point2d;
typedef struct { // save previous row data for polyfill
double x,y,z; // 3d location
} point3d;
/*-----------------------------------------------------------------
find var
*/
double getvar(char *name) { int i;
for (i=0; i<nv; ++i)
if (!strcmp(name,ivar[i].name)) return ivar[i].value;
return 0.0;
}
/*-----------------------------------------------------------------
min and max
*/
double mind(double x, double y) {
return min(x,y);
}
double maxd(double x, double y) {
return max(x,y);
}
/*-----------------------------------------------------------------
gray_palette
*/
void gray_palette()
{
int i;
for (i=0; i<120; ++i) pal[i].r = pal[i].g = pal[i].b = i/2+3;
for (i=120; i<240; ++i) pal[i].r = pal[i].g = pal[i].b = 123-i/2;
for (i=0; i<240; ++i) pal[i+240] = pal[i];
}
/*-----------------------------------------------------------------
wave_palette
*/
#define cwav(r) 31*(sin((i+r)*M_PI/120)+1)
// #define cwav(r) max(min(abs((i+r)%240-120)-40,40),0)*63/40
void wave_palette()
{
int i;
for (i=0; i<240; ++i) {
pal[i].r = cwav(0);
pal[i].g = cwav(80);
pal[i].b = cwav(160);
}
for (i=0; i<240; ++i) pal[i+240] = pal[i];
}
/* positive modulo */
long pmod(long x,long y) {
if (y==0) return x;
if (y<0) y=-y;
x = x % y;
if (x < 0) x += y;
return x;
}
/*-----------------------------------------------------------------
set_palette - set the top 240 colors of the vga palette
*/
void set_palette(int i)
{
struct REGPACK r;
i = pmod(i,240);
r.r_ax = 0x1012;
r.r_bx = 0x0010; /* start */
r.r_cx = 0x00F0; /* length */
r.r_es = FP_SEG(pal);
r.r_dx = FP_OFF(pal) + i*sizeof*pal;
intr(0x10, &r);
}
/*-----------------------------------------------------------------
eval - return value of p, using ivar
*/
double eval(node *p) {
double u,v;
if (!p) return 0;
switch (p->kind) {
case VAR: return getvar(p->name);
case NUM: return p->value;
case ADD: return eval(p->lf) + eval(p->rt);
case SUB: return eval(p->lf) - eval(p->rt);
case MUL: return eval(p->lf) * eval(p->rt);
case DIV:
v = eval(p->rt);
if (fabs(v)<err) return 0;
return eval(p->lf) / v;
case EXP:
u = eval(p->lf);
v = eval(p->rt);
if (u<err && !whole(v)) modf(v,&v); // result would be imaginary
if (fabs(v * log10(fabs(u)+1)) > 300) return 0;
if (!v) return 0;
return pow(u,v);
case EQU: return mind(eval(p->lf),eval(p->rt));
case FUN:
if (!strcmp(p->name,"sin")) return sin(eval(p->lf));
if (!strcmp(p->name,"cos")) return cos(eval(p->lf));
if (!strcmp(p->name,"tan")) return tan(eval(p->lf));
if (!strcmp(p->name,"asin")) {
v = eval(p->lf);
if (v>1 || v<-1) return 0;
return asin(v);
}
if (!strcmp(p->name,"acos")) {
v = eval(p->lf);
if (v>1 || v<-1) return 0;
return acos(v);
}
if (!strcmp(p->name,"atan")) return atan(eval(p->lf));
if (!strcmp(p->name,"sinh")) return sinh(eval(p->lf));
if (!strcmp(p->name,"cosh")) return cosh(eval(p->lf));
if (!strcmp(p->name,"tanh")) return tanh(eval(p->lf));
if (!strcmp(p->name,"rand")) return eval(p->lf)*rand()/RAND_MAX;
if (!strcmp(p->name,"sign")) {
v = eval(p->lf);
return v<0?-1:v>0?1:0;
}
if (!strcmp(p->name,"ln")) {
v = eval(p->lf);
if (v<=0) return 0;
return log(v);
}
if (!strcmp(p->name,"log")) {
v = eval(p->lf);
if (v<=0) return 0;
return log10(v);
}
if (!strcmp(p->name,"abs")) return fabs(eval(p->lf));
if (!strcmp(p->name,"r") && p->nump==2) return hypot(eval(p->lf),eval(p->rt));
if (!strcmp(p->name,"min") && p->nump==2) return mind(eval(p->lf),eval(p->rt));
if (!strcmp(p->name,"max") && p->nump==2) return maxd(eval(p->lf),eval(p->rt));
if (!strcmp(p->name,"atan2") && p->nump==2) {
u = eval(p->lf);
v = eval(p->rt);
if (v==0 && u==0) return 0;
return atan2(u,v);
}
if (!strcmp(p->name,"mod") && p->nump==2) return fmod(eval(p->lf),eval(p->rt));
default: return 0;
}
}
/*-----------------------------------------------------------------
reset window, use a weird number for xs to get better safety
*/
void resetx() { int i;
xs = 7-M_PI/13; ys = xs*0.75;
xo=xs/-2; yo=ys/-2; np=25;
err = pow(10,-sigdig); step=1.0;
for (i=0; i<10; ++i) ivar[i].value = 0;
cz=2.5; cy=2.58819; cx=9.33013; // camera location
ax=.261799; ay=M_PI/2+ax; az=0; // camera orientation
ts=xs; to=xo; vix=1;
co1=15; co2=2; co3=1; rain=0;
focalen=5; fill=0; polar=0; cont=0.2;
}
/*-----------------------------------------------------------------
add a new var
*/
void addvar(char *name) { int i;
for (i=0; i<nv; ++i) if (!strcmp(name,ivar[i].name)) break;
if (i==nv && nv<10) strcpy(ivar[nv++].name,name);
}
/*-----------------------------------------------------------------
look for the first var in p
*/
void setivar(node *p) { int i;
if (p->kind==VAR) addvar(p->name);
for (i=0; i<p->nump; ++i) setivar(p->parm[i]);
}
/*-----------------------------------------------------------------
show help file
*/
void showghelp() {
FILE *f;
int i,c=0;
static char s[85];
strcpy(s,"alged");
strcat(s,lang);
strcat(s,".hlq");
f = fopen(s,"r");
if (!f) { printf(msg[16],s);
pause; return;
}
restorecrtmode();
if (ti.screenheight>25) textmode(64); /* ega 43 line mode */
textattr(norm);
clrscr();
i = ti.screenheight-1;
while (!feof(f)) {
printf(fgets(s,80,f));
if (!--i) {
i = ti.screenheight-4;
while (!(c=getch()));
if (c==27) break;
}
}
if (c!=27) getch();
fclose(f);
setgraphmode(gmode);
}
/*-----------------------------------------------------------------
rotate vars starting at index i
*/
void rot_var(int i) {
node t;
if (nv < 2) return;
t = ivar[i];
t.value = 0;
for (++i; i<nv; ++i) {
ivar[i-1] = ivar[i];
ivar[i-1].value = 0;
}
ivar[nv-1] = t;
strcpy(defx->name,ivar[0].name); // default fx is ivar[0]
}
/*-----------------------------------------------------------------
handle key
*/
void handlekey(char c) {
switch (c) {
case ';': showghelp(); break; /* F1 */
case 72: yo+=ys/4; break;
case 75: xo-=xs/4; break;
case 77: xo+=xs/4; break;